﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace DreamOnGameEngine.Localization
{
    /// <summary>
    /// Single loclization file
    /// </summary>
    public class LocaleFile
    {
        public Dictionary<string, string> m_sStrings;
        /// <summary>
        /// Default Constructor
        /// </summary>
        public LocaleFile()
        {
            m_sStrings = new Dictionary<string, string>();
        }
        /// <summary>
        /// Loads a strings file
        /// </summary>
        /// <param name="fileName">File to load</param>
        /// <returns><c>true</c> if loaded successfully</returns>
        public bool Load(string fileName)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(fileName);
                XmlNode main = doc.ChildNodes[1];
                XmlNodeList text = main.ChildNodes;
                foreach (XmlNode child in text)
                {
                    string ID = child.ChildNodes[0].InnerText;
                    string format = child.ChildNodes[1].InnerText;
                    m_sStrings.Add(ID, format);
                }
                tokenReplace();
                return true;
            }
            catch (Exception e)
            {
                return false;
            }
        }
        /// <summary>
        /// Replaces all tokens with the equivelent values
        /// </summary>
        private void tokenReplace()
        {
            Dictionary<string, string> strings = new Dictionary<string, string>(m_sStrings);
            foreach (KeyValuePair<string,string> form in strings)
            {
                string Val = form.Value;
                if (Val.Contains("{{"))
                {
                    while (Val.Contains("{{"))
                    {
                        int pos = Val.IndexOf("{{", 0);
                        while (pos != -1)
                        {
                            int end = Val.IndexOf("}}", pos);
                            string token = Val.Substring(pos + 2, end - pos - 2);
                            
                            string value = this[token];
                            if (value == null)
                            {
                                value=Localization.Get(token);
                            }
                            if (value == null)
                                throw new Exception("Non existant Token: " + token);
                            Val = Val.Replace("{{" + token + "}}", value);
                            pos = Val.IndexOf("{{", 0);
                        }
                    }
                }
                Val = Val.Replace("{/{", "{{");
                m_sStrings.Remove(form.Key);
                m_sStrings.Add(form.Key, Val);

                
            }
        }
        /// <summary>
        /// Returns the equivelent value
        /// </summary>
        /// <param name="name">Key of the text wished</param>
        /// <returns>Value corresponding to key</returns>
        public string this[string name]
        {
            get
            {
                string form;
                bool succ = m_sStrings.TryGetValue(name, out form);
                if (succ)
                    return form;
                else
                    return null;
            }
        }
        /// <summary>
        /// Returns value corresponding to key, properly formated
        /// </summary>
        /// <param name="name">Key</param>
        /// <param name="args">Values for formatting</param>
        /// <returns>Properly formatted value</returns>
        public string Get(string name, params string[] args)
        {
            string form;
            bool succ = m_sStrings.TryGetValue(name, out form);
            if (succ)
            {
                return string.Format(form, args);
            }
            else
                return null;
        }

    }
}
